/**
 * Simple RSS  Viewer
 * @class Footbar.TreeUtil
 * @static
 */
if (typeof Footbar == "undefined") {
    Footbar = {};
}

var sidebarDocument=this.content.document;
var log = new Log(Log.DEBUG, Log.fileLogger);
Footbar.Srv={
    config:{
        displayReadFeed:true
    },
    serializerFeedDataPath:Footbar.Util.findPluginPath(true)+"chrome\\content\\xml\\serializedFeedData.txt",
    lastFeedData:{},
    data:[],
/**
 * Way the feeds are sorted.
 * 0=Source
 * 1=By Title
 */
    sortMode:0,
    dataSetKeys:[],
    dataFeedInfo:[],
    lastSelectedRow:null,
    fetchQue:0,
    isFeedDownloading:false,

/**
 * Related to the Timer
 */
    initalTime:2*60000,
    remaining:2*60000, //1 Minute = 60000
    intervalID:-1,
    isPaused:false,

/**
 * Initalize Module
 */
    init:function(){
        this.lastFeedData={
            data:[]
        }

        if(nsPreferences.getIntPref("trucoder.reader.sort_order")!=null){
            this.sortMode=nsPreferences.getIntPref("trucoder.reader.sort_order");
        }

        dump("\n  this.sortMode="+ this.sortMode)
        //cast 
        var autoUpdate = !nsPreferences.getBoolPref("trucoder.reader.autoupdate");
        dump("\n autoUpdate="+autoUpdate);
        if(autoUpdate){
            var autoUpdateIntertval=parseInt(nsPreferences.copyUnicharPref("trucoder.reader.autoupdate_interval"));
            this.initalTime=autoUpdateIntertval*60000;
            this.remaining=autoUpdateIntertval*60000;
        }else{
            this.pause(true)
        }

        //DeSerialize DATA From Datafile
        if(Footbar.Util.fileExist(this.serializerFeedDataPath))	{
            this.lastFeedData=JSON.parse( Footbar.Util.readFile(this.serializerFeedDataPath) )
        }

        var tree=document.getElementById('footbar-set-tree-srv-monitor');
        var findXY=function(e){
            var posx=tree.boxObject.screenX;
            var posy=tree.boxObject.screenY ;
            posx +=  e.clientX;
            posy +=  e.clientY-50;
            if(e.button==2){
                // document.getElementById('clipmenu').showPopup(sidebarDocument.documentElement, posx, posy, "bottomleft", "topleft");
                document.getElementById('clipmenu').showPopup(document.documentElement, posx, posy,  "bottomleft", "topleft");
            }  else{
                Footbar.Srv.readFeed();
            }
        }
        tree.addEventListener("mousedown",findXY, false);


        this.initTimer();
        this.populateMaitenanceTree();
        this.populateCategoriesTree();
    },
/**
 * Update Properities when sort type 
 */
    updateSortProperties:function(elem){
        var value=parseInt(elem.getAttribute("value"));
        nsPreferences.setIntPref('trucoder.reader.sort_order', value);
        this.sortMode=value;

    },

    populateCategoriesTree:function(){
        //Prepare the tree : delete all the node from the treechildren
        var tree=document.getElementById( 'footbar-tree-srv-categories' );
        var rootElements=tree.getElementsByTagName("treechildren")[0];
        try {
            while (rootElements.firstChild){
                rootElements.removeChild(rootElements.firstChild);
            };
        } catch(e) {
            alert(e)
        }
        var xmldata = this.loadSourceXML();
        var root = xmldata.getElementsByTagName("root")[0];
        var items = root.getElementsByTagName("set");

        var tree=document.getElementById( 'footbar-tree-srv-categories' );
        var	treechildren = tree.getElementsByTagName("treechildren")[0];

        for (var i=0;i<items.length;i++){
            var itemrow=items[i];

            treechildren.appendChild( Footbar.TreeUtil.cellNode({
                label:itemrow.getAttribute("name"),
                key:itemrow.getAttribute("key"),
                properties:"unread"
            })  );
        }
    },
/**
 * Populate Maitenance Tree : init, afterSave etc...
 */
    populateMaitenanceTree:function(){
        //Prepare the tree : delete all the node from the treechildren
        var tree=document.getElementById( 'footbar-set-tree-srv-maitenance' );
        var rootElements=tree.getElementsByTagName("treechildren")[0];
        try {
            while (rootElements.firstChild){
                rootElements.removeChild(rootElements.firstChild);
            };
        } catch(e) {
            alert(e)
        }


        var xmldata = this.loadSourceXML();
        var root = xmldata.getElementsByTagName("root")[0];
        var items = root.getElementsByTagName("set");


        var tree=document.getElementById( 'footbar-set-tree-srv-maitenance' );
        var	treechildren = tree.getElementsByTagName("treechildren")[0];

        for (var i=0;i<items.length;i++){
            var itemrow=items[i];

            var label_title= document.createElement("treecell");
            label_title.setAttribute("label",  itemrow.getAttribute("name"))
            label_title.setAttribute("key",  itemrow.getAttribute("key"))
            label_title.setAttribute("properties","unread");
            var	treerow = document.createElement("treerow");
            treerow.setAttribute("id",  "setname-treerow-"+i);

            var	treeitem = document.createElement("treeitem");
            treeitem.setAttribute("container", "true");
            treeitem.setAttribute("open", "true");


            var  sub_treechildren = document.createElement("treechildren");
            var uriList=itemrow.getElementsByTagName("item");
            for(var k=0;k<uriList.length;k++){
                sub_treechildren.appendChild( Footbar.TreeUtil.cellNode({
                    label:uriList[k].getAttribute("title"),
                    key:uriList[k].getAttribute("key"),
                    uri:uriList[k].getAttribute("uri"),
                    properties:"read"
                }) );

            }

            treerow.appendChild(label_title);
            treeitem.appendChild(treerow);
            treeitem.appendChild(sub_treechildren);
            treechildren.appendChild(treeitem);

        }
    },
/**
 * @extends Array.js
 * @param {Object} key
 */
    findDataSetKey:function(key){
        var arr=[];
        for(var i=0;i<this.dataSetKeys.length;i++){
            arr=[];
            arr=this.dataSetKeys[i];
            if(this.dataSetKeys[i].indexOf(key)>-1){
                return i;
            }
        }
        return -1;
    },
/**
 * Edit Selected Row
 */
    editSelectedRow:function(){
        var eCategory=document.getElementById('footbar-srv-feedcategory');
        var eFeedName=document.getElementById('footbar-srv-feedname');
        var eFeedURI=document.getElementById('footbar-srv-feeduri');
        var selectedRow=Footbar.TreeUtil.getSelectedRow('footbar-set-tree-srv-maitenance');

        if(!selectedRow){
            selectedRow=this.lastSelectedRow;
        }else{
            this.lastSelectedRow=selectedRow;
        }

        var rowData;
        rowData=selectedRow.getElementsByTagName('treecell')[0];

        if(selectedRow.hasAttribute("container")){
            eCategory.setAttribute("readonly", true);

            eCategory.value=rowData.getAttribute("label");
            eFeedName.value=""
            eFeedURI.value=""
        }else{

            eFeedName.value=rowData.getAttribute("label");
            eFeedURI.value=rowData.getAttribute("uri");

            var parentRowData=Footbar.TreeUtil.findParentNode( selectedRow );
            eCategory.value=parentRowData.getAttribute("label");
            eCategory.setAttribute("readonly", true);
        }

    },
/**
 * Add new Category
 */
    categoryNew:function(){
        var uid=Footbar.Util.uid();
        var xmlDoc=this.loadSourceXML();
        var root=xmlDoc.getElementsByTagName('root')[0];
        var newNode=document.createElement('set');
        newNode.setAttribute("name","Category "+uid);
        newNode.setAttribute("key", uid);
        root.appendChild(newNode);

        var filePath=Footbar.Util.findPluginPath(true)+"chrome\\content\\xml\\srv-sets-data.xml";
        var output='<?xml version="1.0" encoding="iso-8859-1"?>\n'+Footbar.Util.serializeNode(xmlDoc, 0);
        Footbar.Util.writeFileData(filePath, output);

        this.populateCategoriesTree();
        this.populateMaitenanceTree();
    },
/**
 * Edit Category
 */
    categoryEdit:function(){
        //footbar-tree-srv-categories
        var selected=Footbar.TreeUtil.getSelectedRow('footbar-tree-srv-categories');
        var rowData=selected.getElementsByTagName('treecell')[0];
        var txtCat=document.getElementById('footbar-srv-categoryName');
        txtCat.value=rowData.getAttribute('label');

    },
/**
 * Save Edited Category
 */
    categorySave:function(){
        Footbar.TreeUtil.suppresEvents('footbar-tree-srv-categories')
        var selected=Footbar.TreeUtil.getSelectedRow('footbar-tree-srv-categories');
        var rowData=selected.getElementsByTagName('treecell')[0];
        var uid=rowData.getAttribute('key');
        var txtCat=document.getElementById('footbar-srv-categoryName');
        try {
            var xmlDoc=this.loadSourceXML();
            var root=xmlDoc.getElementsByTagName('root')[0];
            var iteratorRow = xmlDoc.evaluate( '/root/set[@key="'+uid+'"]', xmlDoc, null, XPathResult.ANY_TYPE, null );
            var thisNode = iteratorRow.iterateNext();

            thisNode.setAttribute('name', escapeXML(txtCat.value));

            var filePath=Footbar.Util.findPluginPath(true)+"chrome\\content\\xml\\srv-sets-data.xml";
            var output='<?xml version="1.0" encoding="iso-8859-1"?>\n'+Footbar.Util.serializeNode(xmlDoc, 0);
            Footbar.Util.writeFileData(filePath, output);


            this.populateCategoriesTree();
            this.populateMaitenanceTree();

        }
        catch (e) {
            alert( e );
        }

    },
/**
 * Update or save Currently edited Feed
 */
    updateSaveSet:function(){
        var eFeedName=document.getElementById('footbar-srv-feedname');
        var eFeedURI=document.getElementById('footbar-srv-feeduri');
        var selectedRow=this.lastSelectedRow;


        if(selectedRow.hasAttribute("container")){
            var data=selectedRow.getElementsByTagName('treecell')[0];
            var uid=data.getAttribute("key");

            try {
                var xmlDoc=this.loadSourceXML();
                var root=xmlDoc.getElementsByTagName('root')[0];
                var iteratorRow = xmlDoc.evaluate( '/root/set[@key="'+uid+'"]', xmlDoc, null, XPathResult.ANY_TYPE, null );
                var thisNode = iteratorRow.iterateNext();
                var newNode=document.createElement('item');
                newNode.setAttribute('title', eFeedName.value);
                newNode.setAttribute('uri', eFeedURI.value);
                newNode.setAttribute('key', Footbar.Util.uid());

                thisNode.appendChild(newNode);

                var filePath=Footbar.Util.findPluginPath(true)+"chrome\\content\\xml\\srv-sets-data.xml";
                var output='<?xml version="1.0" encoding="iso-8859-1"?>\n'+Footbar.Util.serializeNode(xmlDoc, 0);
                Footbar.Util.writeFileData(filePath, output);

                this.populateMaitenanceTree();

            }
            catch (e) {
                alert( e );
            }


        }else{
            var data=selectedRow.getElementsByTagName('treecell')[0];
            var uid=data.getAttribute("key");

            try {
                var xmlDoc=this.loadSourceXML();
                var root=xmlDoc.getElementsByTagName('root')[0];
                var iteratorRow = xmlDoc.evaluate( '/root/set/item[@key="'+uid+'"]', xmlDoc, null, XPathResult.ANY_TYPE, null );
                var thisNode = iteratorRow.iterateNext();

                thisNode.setAttribute('title', eFeedName.value);
                thisNode.setAttribute('uri', eFeedURI.value);

                var filePath=Footbar.Util.findPluginPath(true)+"chrome\\content\\xml\\srv-sets-data.xml";
                var output='<?xml version="1.0" encoding="iso-8859-1"?>\n'+Footbar.Util.serializeNode(xmlDoc, 0);
                Footbar.Util.writeFileData(filePath, output);

                this.populateMaitenanceTree();

            }
            catch (e) {
                alert( e );
            }

        }
    },


    markRowAsRead:function(){
        Footbar.TreeUtil.markRowAsRead('footbar-set-tree-srv-monitor');

        var selected=Footbar.TreeUtil.getSelectedRow('footbar-set-tree-srv-monitor');
        selected=selected.getElementsByTagName('treecell')[0];
        var key=selected.getAttribute("key");
        this.data[key].read=true;
      

    },
    markRowAsUnRead:function(){
       /*
        var selected=Footbar.TreeUtil.getSelectedRow('footbar-set-tree-srv-monitor');
        if(!selected)return;
        this.data[selected.getAttribute("key")].read=false;
        Footbar.TreeUtil.markRowAsUnRead('footbar-set-tree-srv-monitor');
        */
    },

/**
 * Read currently selected Node
 */
    readFeed:function(){
        var self=this;

        const singleDisplayURI='chrome://footbar/content/xml/display.html';
        const multipleDisplayURI='chrome://footbar/content/xml/display.html';
        var executeURI="";
        var mode="single";
        var selected=Footbar.TreeUtil.getSelectedRow('footbar-set-tree-srv-monitor');

        if(!selected)return;

        if(selected.hasAttribute('container')){
            executeURI=multipleDisplayURI;
            mode="multiple";
            var key=selected.getAttribute("key");
            var keys=Footbar.Srv.dataSetKeys[ key ];
            var templatePathInFinal=Footbar.Util.findPluginPath(true)+"chrome\\content\\xml\\srv-multiple-template.xml";
            var templatePathIn=Footbar.Util.findPluginPath(true)+"chrome\\content\\xml\\srv-multiple-display-template.xml";
            var templatePathInChannelWrapper=Footbar.Util.findPluginPath(true)+"chrome\\content\\xml\\srv-multiple-display-template-channel.xml";


            var templateData=Footbar.Util.readFile(templatePathIn);
            var output="";

            var  uniqueDataSets=[];
            for(var i=0;i<keys.length;i++){
                if(uniqueDataSets.indexOf( this.data[keys[i]].feedID )==-1){
                    uniqueDataSets[uniqueDataSets.length] = this.data[keys[i]].feedID;
                }
            }
            uniqueDataSets.sort();

            for(var k=0;k<uniqueDataSets.length;k++){
                var currentFeedID=uniqueDataSets[k];
                var filteredKeys=keys.filter(function(element, index, array){
                    return (self.data[element].feedID==currentFeedID);
                });

                var molderChannel=new Footbar.FireTag();
                molderChannel.setTemplate( Footbar.Util.readFile(templatePathInChannelWrapper) );

                var itemCollector="";
                for(var i=0;i<filteredKeys.length;i++){
                    var molder=new Footbar.FireTag();
                    molder.setTemplate( templateData );
                    molder.addVariable('title', this.data[filteredKeys[i]].title);
                    molder.addVariable('link', this.data[filteredKeys[i]].link);
                    molder.addVariable('description', this.data[filteredKeys[i]].description);
                    molder.addVariable('pubDate', this.data[filteredKeys[i]].pubDate);

                    itemCollector+= molder.run();
                }

                if(filteredKeys.length>0){
                    var oFeedInfo={};
                    oFeedInfo=Footbar.Srv.dataFeedInfo[ currentFeedID ];
                    dump('\n channel_title='+ oFeedInfo.title);

                    molderChannel.addVariable('channel_title', oFeedInfo.title);
                    molderChannel.addVariable('channel_description', oFeedInfo.description);
                    molderChannel.addVariable('entries', itemCollector);
                    output+=molderChannel.run()+"\n";

                }

            }

            var templatePathOut=Footbar.Util.findPluginPath(true)+"chrome\\content\\xml\\srv-multiple-display.xml";
            var molder=new Footbar.FireTag();
            molder.setTemplate( Footbar.Util.readFile(templatePathInFinal) );
            molder.addVariable('generated', output);
            var outputFinal=molder.run();

            Footbar.Util.writeFileData(templatePathOut, outputFinal);

        }else{
            executeURI=singleDisplayURI;
            mode="single";
            Footbar.TreeUtil.markRowAsRead('footbar-set-tree-srv-monitor');
            selected=selected.getElementsByTagName('treecell')[0];
            var key=selected.getAttribute("key");
            var templatePathIn=Footbar.Util.findPluginPath(true)+"chrome\\content\\xml\\srv-single-display-template.xml";
            var templatePathOut=Footbar.Util.findPluginPath(true)+"chrome\\content\\xml\\srv-single-display.xml";
            var templateData=Footbar.Util.readFile(templatePathIn);

            var molder=new Footbar.FireTag();
            molder.setTemplate( templateData );

            var oFeedInfo={};
            oFeedInfo=Footbar.Srv.dataFeedInfo[ this.data[key].feedID ];
            molder.addVariable('channel_title', oFeedInfo.title);
            molder.addVariable('channel_description', oFeedInfo.description);


            molder.addVariable('title', this.data[key].title);
            molder.addVariable('link', this.data[key].link);
            molder.addVariable('description', this.data[key].description);
            molder.addVariable('pubDate', this.data[key].pubDate);
            var output=molder.run();
            //Feed have been read
            this.data[key].read=true;
            Footbar.Util.writeFileData(templatePathOut, output);

        }

        var gBrowser=Footbar.Util.getBrowser();
        var executeURI;
        //Check if the URI is open
        if(Footbar.Util.isTabURIOpen( executeURI )){
            Footbar.Util.focusTab( executeURI );
        }else{
            // Add tab, then make active
            gBrowser.selectedTab = gBrowser.addTab( executeURI );
            gBrowser.focus();
        }

        //Grab DOM and call execute to apply XSL stylesheet
        var domSet=Footbar.Util.getTabDOM( executeURI );
        //call execute method in the open Tab
        //this will reload the xml and xls files
        try{
            domSet.window.execute(mode);
        }catch(e){
            dump(e);
        }


        //Store last FeedData
        this.lastFeedData.data=this.stripedData();
        //Serialize DATA TO a XML File so it can be restored later
        Footbar.Util.writeFileData(this.serializerFeedDataPath, JSON.stringify( this.lastFeedData ));

    },
/**
 * Return stripped data object that only contains necessary information
 * So stuff like title , description won't be save
 */
    stripedData:function(){
        var tempData=[];
        var len=this.data.length;
        for(var i=0;i<len;i++){
            tempData[i]={
                hash:this.data[i].hash,
                read:this.data[i].read
            }
        }
        return tempData;
    },
/**
 * Update RSS Feed
 */
    updateFeed:function(){

        //Reset
        this.dataSetKeys=[];
        this.dataFeedInfo=[];
        this.data=[];

        this.isFeedDownloading=true;
        var tree=document.getElementById('footbar-set-tree-srv-monitor');
        //pause the Timer if its enabled
        var originalPause=this.isPaused;
        //pause the Timer if its enabled
        if(!this.isPaused){
            this.pause();
        }
        Footbar.TreeUtil.suppresEvents( tree.view.selection );
        //Prepare the tree : delete all the node from the treechildren

        var rootElements=document.getElementById("footbar-set-tree-srv-monitor-children");
        try {
            while (rootElements.firstChild){
                rootElements.removeChild(rootElements.firstChild);
            };
        } catch(e) {
            alert(e)
        }


        var xmldata = this.loadSourceXML();
        var root = xmldata.getElementsByTagName("root")[0];
        var items = root.getElementsByTagName("set");

        var tree=document.getElementById( 'footbar-set-tree-srv-monitor' );
        var	treechildren = tree.getElementsByTagName("treechildren")[0];

        for (var i=0;i<items.length;i++){
            var itemrow=items[i];

            var label_title= document.createElement("treecell");
            label_title.setAttribute("label",  itemrow.getAttribute("name"))
            label_title.setAttribute("key",  itemrow.getAttribute("key"))
            label_title.setAttribute("properties","unread");
            var	treerow = document.createElement("treerow");
            treerow.setAttribute("id",  "setname-treerow-"+i);

            var	treeitem = document.createElement("treeitem");
            treeitem.setAttribute("container", "true");
            treeitem.setAttribute("open", "true");
            treeitem.setAttribute("key", i);


            var  sub_treechildren = document.createElement("treechildren");
            var uriList=itemrow.getElementsByTagName("item");
            for(var k=0;k<uriList.length;k++){
                var uri=uriList[k].getAttribute("uri");
                (new Fetcher(i, uri, sub_treechildren, k)).load();
            }

            treerow.appendChild(label_title);
            treeitem.appendChild(treerow);
            treeitem.appendChild(sub_treechildren);
            treechildren.appendChild(treeitem);
        }
        //Resume Timer only if original timer was notPaused
        if(this.isPaused && !originalPause){
            this.pause();
        }else{
            this.pause(true);
        }

        //Make Tree Clickable again
        Footbar.TreeUtil.restoreSuppresedEvents( );
    },

/**
 * Initailize the Timer
 */
    initTimer:function(){
        this.intervalID = setInterval(function(){
            var label=document.getElementById("footbar-srv-nextupdate-label");

            var minutes=Math.floor(Footbar.Srv.remaining/(60000));
            var seconds=Math.floor((Footbar.Srv.remaining%60000)/1000);
            label.label=" Next Feed Update In    "+minutes+" : "+seconds+"  ";

            Footbar.Srv.remaining-=1000;
            if(minutes<=0 && seconds<=0){
                Footbar.Srv.remaining=Footbar.Srv.initalTime;
                Footbar.Srv.updateFeed();
            }
        }, 1000);
    },
    pauseToggle:function(){
        this.isFeedDownloading=false;
        this.pause();
    },
/**
 * Pause/unpause the update manager
 */
    pause:function(forcePause){
        var self=this;
        var label=document.getElementById("footbar-srv-nextupdate-label");
        var btnUpdateNow=document.getElementById("footbar-srv-nowupdate-label");
        if(!this.isPaused || forcePause){
            clearInterval(this.intervalID);
            label.image="/skin/pause.png"
            label.label="Paused";
            this.isPaused=true;
            if(this.isFeedDownloading){
                label.image="/skin/indicator.gif"
                label.label="Fetching RSS Feed";
                label.disabled=true;
                btnUpdateNow.disabled = true;
            }
        }else{
            var fetchInterval;
            fetchInterval=setInterval(function(){
                if(Footbar.Srv.fetchQue==0){
                    clearInterval(fetchInterval);
                    btnUpdateNow.disabled = false;
                    this.isPaused=false;
                    label.image="/skin/timestamp.png";
                    label.label="Resuming";
                    label.disabled=false;
                    Footbar.Srv.initTimer();
                    this.isFeedDownloading=false;

                    //if ( nsPref.getBoolPref("scrapbook.notifyOnComplete", true) )
                {
                    Footbar.Util.notifyMessage("Feeds updated");
                }


                }
            },100);
            this.isPaused=false;
        }
    },

/**
 * Load Set XML File
 */
    loadSourceXML:function(){
        var url="chrome://footbar/content/xml/srv-sets-data.xml"
        var httpRequest;
        httpRequest = new XMLHttpRequest();
        httpRequest.overrideMimeType('text/xml');
        httpRequest.open('GET', url, false);
        httpRequest.send(null);
        return httpRequest.responseXML;
    }
}
/**
 * Inner class to retive xml Feeds
 * @param {Object} setKey
 * @param {Object} uri
 * @param {Object} node
 */

function Fetcher(setKey, uri, node){
    this.setKey=setKey;
    this.gXMLHttpRequest=null;
    this.node=node;
    this.uri=uri;
    this.xmldata=null;
    // this.feedID=feedID;
}

Fetcher.prototype.load=function(){

    //@ Ref http://www.captain.at/howto-ajax-permission-denied-xmlhttprequest.php
    try {
        netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
    } catch (e) {
        alert("Permission UniversalBrowserRead denied.");
        return "";
    }
    dump("\n fetching   >"+this.uri);

    Footbar.Srv.fetchQue++;
    var self=this;
    this.gXMLHttpRequest = new XMLHttpRequest();
    this.gXMLHttpRequest.onload = function() {

        if(this.readyState == 4 && this.status == 200){
            this.xmldata = (new DOMParser()).parseFromString(this.responseText, "text/xml");

            self.update(this.xmldata);
            Footbar.Srv.fetchQue--;
        }else{
            log.error("Fetcher > "+self.uri+"<br />"+this.responseText);
            Footbar.Srv.fetchQue--;
        }
    };	; // the function to call when fetching data
    this.gXMLHttpRequest.open("GET", this.uri, true); // make the get request
    this.gXMLHttpRequest.send(null);
}

/**
 * Detect type of the current Feed RSS = 1 ATOM=2;
 * Very simple method at this time
 */
Fetcher.prototype.detectFeedType=function(xmlDoc){
    var type=1;
    var resultsetIterator = xmlDoc.evaluate('/rss/channel', xmlDoc, null, XPathResult.ANY_TYPE, null );
    var resultset=resultsetIterator.iterateNext();
    if(resultset==null){
        type=2;
    }
    return type;
}
/**
 * Parse RSS Feed
 * @param {Object} xmlDoc
 */
Fetcher.prototype.parseRSSFeed=function(xmlDoc){
    //Retrive Feed Info
    var oChannelInfo={};
    var resultsetIterator = xmlDoc.evaluate('/rss/channel', xmlDoc, null, XPathResult.ANY_TYPE, null );
    var resultset=resultsetIterator.iterateNext();
    var title=resultset.getElementsByTagName("title")[0];

    try{
        title=title.textContent;
        oChannelInfo.title=escapeXML(title);
    }catch(e){
        oChannelInfo.title="n/a";
    }

    var description=resultset.getElementsByTagName("description")[0];
    try{
        description=description.textContent;
        oChannelInfo.description=escapeXML(description);
    }catch(e){
        oChannelInfo.description="n/a";
    }

    var feedIDHash=this.uri.hashCode();
    Footbar.Srv.dataFeedInfo[feedIDHash]=oChannelInfo;


    //var currentSet=Footbar.Srv.dataSetKeys[this.setKey] || [];
    var currentSet = [];
    var query="/rss/channel/item";
    var resultsetIterator = xmlDoc.evaluate( query, xmlDoc, null, XPathResult.ANY_TYPE, null );
    var resultset=resultsetIterator.iterateNext();
    while(resultset){
        var title=resultset.getElementsByTagName("title")[0];
        title=title.textContent;
        title=escapeXML(title);

        var description=resultset.getElementsByTagName("description")[0];
        var description_org=description.textContent;
        description=description.textContent;
        description=escapeXML(description);

        var link=resultset.getElementsByTagName("link")[0];
        link=link.textContent;
        link=escapeXML(link);

        var pubDate=resultset.getElementsByTagName("pubDate")[0];
        if(pubDate){
            pubDate=pubDate.textContent;
        }else{
            pubDate="n/a"
        }
        var hash=(title+link+pubDate).hashCode();

        var key=Footbar.Srv.data.length;
        //Datastructure to hold the info
        Footbar.Srv.data[key]={
            title:title,
            link:link,
            description:description,
            pubDate:pubDate,
            hash:hash,
            read:false,
            feedID:feedIDHash
        }
        currentSet[currentSet.length]=key;
        resultset=resultsetIterator.iterateNext();
    }
    return currentSet;
}

/**
 * 
 * @param {Object} xmlDoc
 */
Fetcher.prototype.parseATOMFeed=function(xmlDoc){
    //http://developer.mozilla.org/en/docs/Introduction_to_using_XPath_in_JavaScript#Iterator_Example
    var nsResolver=function() {
        return 'http://www.w3.org/2005/Atom';
    }

    var oChannelInfo={};
    var resultsetIterator = xmlDoc.evaluate('/def:feed', xmlDoc, nsResolver, XPathResult.ANY_TYPE, null );
    var resultset=resultsetIterator.iterateNext();
    var title=resultset.getElementsByTagName("title")[0];

    try{
        title=title.textContent;
        oChannelInfo.title=escapeXML(title);
    }catch(e){
        oChannelInfo.title="n/a";
    }

    var description=resultset.getElementsByTagName("subtitle")[0];
    try{
        description=description.textContent;
        oChannelInfo.description=escapeXML(description);
    }catch(e){
        oChannelInfo.description="n/a";
    }

    var feedIDHash=this.uri.hashCode();
    Footbar.Srv.dataFeedInfo[feedIDHash]=oChannelInfo;


    // var currentSet=Footbar.Srv.dataSetKeys[this.setKey] || [];
    var currentSet = [];
    var query="/def:feed/def:entry";
    var resultsetIterator = xmlDoc.evaluate( query, xmlDoc, nsResolver, XPathResult.ANY_TYPE, null );

    var resultset=resultsetIterator.iterateNext();
    while(resultset){
        var title=resultset.getElementsByTagName("title")[0];
        title=title.textContent;
        title=escapeXML(title);

        var description=resultset.getElementsByTagName("summary")[0];
        var description_org=description.textContent;
        description=description.textContent;
        description=escapeXML(description);

        var link=resultset.getElementsByTagName("link")[0];
        link=link.textContent;
        link=escapeXML(link);

        var pubDate=resultset.getElementsByTagName("updated")[0];
        if(pubDate){
            pubDate=pubDate.textContent;
        }else{
            pubDate="n/a"
        }
        var hash=(title+link+pubDate).hashCode();
        var key=Footbar.Srv.data.length;
        //Datastructure to hold the info
        Footbar.Srv.data[key]={
            title:title,
            link:link,
            description:description,
            pubDate:pubDate,
            hash:hash,
            read:false ,
            feedID:feedIDHash
        }

        currentSet[currentSet.length]=key;
        resultset=resultsetIterator.iterateNext();
    }
    return currentSet;
}


Fetcher.prototype.update=function(xmlDoc){
    var feedType=this.detectFeedType(xmlDoc);
    var currentSet=[]
    if(feedType==1){
        currentSet = this.parseRSSFeed(xmlDoc);
    }else if(feedType==2){
        currentSet =  this.parseATOMFeed(xmlDoc);
    }

    //currentSet =  currentSet.unique();

    //Sort By Title
    if(Footbar.Srv.sortMode==1){
        currentSet.sort(function(a,b){
            //Case Sensitive compare
            var strA = (new String(Footbar.Srv.data[a].title)).toLowerCase();
            var strB = (new String(Footbar.Srv.data[b].title)).toLowerCase();
            if (strA < strB) {
                return -1;
            }else if (strA > strB) {
                return 1;
            }
            return 0;
        });
    }
    Footbar.Srv.dataSetKeys[this.setKey] =  currentSet;

    //Add nodes after they have been sorted to the tree
    for(var i=0;i<currentSet.length;i++){
        var rowData=Footbar.Srv.data[currentSet[i]];
        var lastFeed=Footbar.Srv.lastFeedData.data;
        var propertiesCSS="unread";
        var showFeedItem=true;

        for(var j=0;j<lastFeed.length;j++){
            if((rowData.hash==lastFeed[j].hash) && lastFeed[j].read){
                showFeedItem=Footbar.Srv.config.displayReadFeed;
                rowData.read=true;
                propertiesCSS="read";
                break;
            }
        }
        if(showFeedItem){
            this.node.appendChild( Footbar.TreeUtil.cellNode({
                label: i+" : "+rowData.title,
                properties:propertiesCSS,
                key:currentSet[i]
            }) );
        }

    }
}
function escapeXML(str){
    //str = str.replace(/</g, '&lt;');
    //str = str.replace(/>/g, '&gt;');
    str = str.replace(/<!\[CDATA/g, 'CDATA_START;');
    str = str.replace(/]]>/g, 'CDATA_END;');

    str = str.replace(/\&(?!\w+;|#\d+;)/g, '&amp;');
    return str;
}